#include <stm32l1xx.h>
#include <vectors.h>
#include <adc.h>
#include <motor.h>

volatile uint16_t adcres[16] = {0};
int adcflag = 0;

void adc_init() {
	SET_BIT(RCC -> APB2ENR,RCC_APB2ENR_ADC1EN); // enable ADC clock
	SET_BIT(RCC -> AHBENR,RCC_AHBENR_GPIOAEN); // enable GPIOA clock => PA0
	if (READ_BIT(ADC1 -> SR,ADC_SR_ADONS))
		CLEAR_BIT(ADC1 -> CR2,ADC_CR2_ADON); // disable ADC, just paranoia*/

	CLEAR_BIT(DMA1_Channel1 -> CCR,DMA_CCR1_EN); // disable DMA
	
	SET_BIT(ADC1 -> CR2,ADC_CR2_ALIGN | ADC_CR2_DMA | ADC_CR2_DDS /*| ADC_CR2_CONT*/); // left-aligned, DMA, DMA is continuous (not one-time only => DDS)
	SET_BIT(ADC1 -> CR1,ADC_CR1_SCAN); // scan mode
	SET_BIT(ADC1 -> CR2,ADC_CR2_EXTSEL_3 | ADC_CR2_EXTSEL_1); // trigger je TIM6 TRGO
	SET_BIT(ADC1 -> CR2,ADC_CR2_EXTEN_0); // trigger on rising edge of TRGO



	SET_BIT(GPIOA -> MODER,GPIO_MODER_MODER3); // PA3 is analog
//	SET_BIT(GPIOA -> MODER,GPIO_MODER_MODER3); // PA1/2/3 are analog
//	SET_BIT(OPAMP -> CSR,OPAMP_CSR_S4SEL1 | OPAMP_CSR_S5SEL1); // S4 a S5
//	CLEAR_BIT(OPAMP -> CSR,OPAMP_CSR_OPA1PD); // opamp1 power-down = 0
//	SET_BIT(OPAMP -> CSR,OPAMP_CSR_S3SEL1 | OPAMP_CSR_S5SEL1); // S3 a S5 - sledovac

//	SET_BIT(GPIOC -> MODER,GPIO_MODER_MODER3); // PC3 are analog
//	GPIOC -> ODR = 0xF;
//	SET_BIT(OPAMP -> CSR,OPAMP_CSR_S4SEL1 | OPAMP_CSR_S5SEL1); // S4 a S5
//	SET_BIT(OPAMP -> CSR,OPAMP_CSR_S3SEL3 | OPAMP_CSR_S5SEL3); // S3 a S5 - sledovac
//	CLEAR_BIT(OPAMP -> CSR,OPAMP_CSR_OPA3PD); // opamp1 power-down = 0


	CLEAR_BIT(ADC1 -> SMPR3,ADC_SMPR3_SMP3); // 4 cycles
	SET_BIT(ADC1 -> SQR5,ADC_SQR5_SQ1_0 | ADC_SQR5_SQ1_1); // channel 3
	SET_BIT(ADC1 -> SQR5,ADC_SQR5_SQ2_0 | ADC_SQR5_SQ2_1); // channel 3 - dummy pre ine
	SET_BIT(ADC1 -> SQR5,ADC_SQR5_SQ3_0 | ADC_SQR5_SQ3_1); // channel 3
	SET_BIT(ADC1 -> SQR5,ADC_SQR5_SQ4_0 | ADC_SQR5_SQ4_1); // channel 3 - dummy pre ine
	SET_BIT(ADC1 -> SQR5,ADC_SQR5_SQ5_0 | ADC_SQR5_SQ5_1); // channel 3
	SET_BIT(ADC1 -> SQR5,ADC_SQR5_SQ6_0 | ADC_SQR5_SQ6_1); // channel 3 - dummy pre ine
	SET_BIT(ADC1 -> SQR4,ADC_SQR4_SQ7_0 | ADC_SQR4_SQ7_1); // channel 3
	SET_BIT(ADC1 -> SQR4,ADC_SQR4_SQ8_0 | ADC_SQR4_SQ8_1); // channel 3 - dummy pre ine
	SET_BIT(ADC1 -> SQR1,ADC_SQR1_L_2 | ADC_SQR1_L_1 | ADC_SQR1_L_0); // osem prevodov
	
	DMA1_Channel1 -> CPAR = (int) &(ADC1 -> DR); // prenasaj UART data register
	DMA1_Channel1 -> CNDTR = 16; // 2x 8 prenos
	DMA1_Channel1 -> CMAR  = (uint32_t) adcres;
	DMA1_Channel1 -> CCR |= DMA_CCR1_MINC | DMA_CCR1_MSIZE_0 | DMA_CCR1_PSIZE_0 | DMA_CCR1_CIRC | DMA_CCR1_HTIE | DMA_CCR1_TCIE;   // from peripheral to memory, 16-bit peripheral and memory, circular mode, trasfer complete and half-complete interrupt enable

	TIM6 -> ARR = 1599; // 16000 kHz / 1600 = 10 kHz, Tvz
	TIM6 -> PSC = 0;

	SET_BIT(TIM6 -> CR2,TIM_CR2_MMS_1); // TRGO on update=>pretecenie

	SET_BIT(TIM6 -> CR1,TIM_CR1_CEN); // start TIM6
	SET_BIT(DMA1_Channel1 -> CCR,DMA_CCR1_EN); // DMA xfer start

//	NVIC_SetPriority(DMA1_Channel1_IRQn,1); // DMA ADCcka ma najvyssiu prioritu, pretoze je sucastou regulacnej slucky
	NVIC_EnableIRQ(DMA1_Channel1_IRQn); // enable DMA interrupt
	SET_BIT(ADC1 -> CR2,ADC_CR2_ADON); // enable ADC
}

static int volanie_wreg; // pocitadlo pre volanie wreg


void DMA1_Channel1_IRQHandler(void) {
	if (++volanie_wreg > 99) { // 100 Hz
		volanie_wreg = 0;
		wREG();
	}
	if (READ_BIT(DMA1 -> ISR,DMA_ISR_HTIF1)) {
		iREG(&adcres[0]);
	}
	if (READ_BIT(DMA1 -> ISR,DMA_ISR_TCIF1)) {
		iREG(&adcres[8]);
	}
	SET_BIT(DMA1 -> IFCR,DMA_IFCR_CGIF1);
}

